package monitoring.sla.parser.slang;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class SlangHandler extends org.xml.sax.helpers.DefaultHandler {
	
	private HashMap<String, String> sla = new HashMap<String, String>();
	private final static String SLAName="SLA";
	private HashMap<String, Double> duration = new HashMap<String, Double>();
	private final static String durationName="Duration";
	private HashMap<String, ThroughputSlang> throughput = new HashMap<String, ThroughputSlang>();
	private final static String throughputName="InputThroughputScheduledSlidingPenaltyClause";
	private HashMap<String, LatencySlang> latency = new HashMap<String, LatencySlang>();
	private final static String latencyName="FixedLatencyFailureModeDefinition";
	private HashMap<String, OperationSlang> operation = new HashMap<String, OperationSlang>();
	private final static String operationName="OperationDefinition";
	
	
	/*
	 * Duration
	 * 
	 * <SLAng:Duration 
	 * 			unit="" 
	 * 			value="" 
	 * 			xmi.id="mofid"/>
	 */
	
	
	/*
	 * Throughput
	 * 
	 * <SLAng:InputThroughputScheduledSlidingPenaltyClause 
	 * 			concurrency="" 
	 * 			sLA="mofid:SLA" 
	 * 			window="mofid:Duration" 
	 * 			xmi.id="mofid"/>
	 */
	
	/*
	 * Tempo di risposta
	 * 
	 * <SLAng:FixedLatencyFailureModeDefinition 
	 * 			electronicService="mofid" 
	 * 			maxDuration="mofid:Duration" 
	 * 			operations="mofid:OperationDefinition" 
	 * 			sLA="mofid:SLA" 
	 * 			xmi.id="mofid"/>
	 */
	
	/*
	 * Operazione
	 * 
	 * <SLAng:OperationDefinition 
	 * 			description="" 
	 * 			operation="mofid" 
	 * 			xmi.id="mofid"/>
	 */
	
	public void startElement(String uri, String localName,
			String qName, Attributes attributes)
	throws SAXException {
		String element=qName.toLowerCase();
		
		if (element.endsWith(SLAName.toLowerCase())) {
			String key="", description="";
			for(int i=0;i<attributes.getLength();i++){
				if(attributes.getQName(i).equalsIgnoreCase("description"))
					description=attributes.getValue(i);
				if(attributes.getQName(i).equalsIgnoreCase("xmi.id"))
					key=attributes.getValue(i);;
			}
			if(key!=null && !key.equals(""))
				sla.put(key, description);
		}
		
		if(element.endsWith(durationName.toLowerCase())){
			double value=-1;
			String unit="", key="";
			for(int i=0;i<attributes.getLength();i++){
				if(attributes.getQName(i).equalsIgnoreCase("unit"))
					unit=attributes.getValue(i);
				if(attributes.getQName(i).equalsIgnoreCase("value"))
					value=Double.valueOf(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("xmi.id"))
					key=attributes.getValue(i);;
			}
			if(key!=null && !key.equals(""))
				convertIntoMs(unit, value, key);	        		
		}

		if (element.endsWith(throughputName.toLowerCase())) {
			ThroughputSlang t = new ThroughputSlang();
			String key="";
			for(int i=0;i<attributes.getLength();i++){
				if(attributes.getQName(i).equalsIgnoreCase("concurrency"))
					t.setConcurrency(Long.valueOf(attributes.getValue(i)));
				if(attributes.getQName(i).equalsIgnoreCase("sla"))
					t.setIdSla(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("window"))
					t.setIdWindow(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("xmi.id"))
					key=attributes.getValue(i);
			}
			if(key!=null && !key.equals(""))
				throughput.put(key, t);
		}
		
		if (element.endsWith(latencyName.toLowerCase())) {
			LatencySlang l = new LatencySlang();
			String key="";
			for(int i=0;i<attributes.getLength();i++){
				if(attributes.getQName(i).equalsIgnoreCase("operations")){
					List<String> idOperations = new ArrayList<String>();
					idOperations.add(attributes.getValue(i));
					l.setIdOperation(idOperations);
				}
				if(attributes.getQName(i).equalsIgnoreCase("sla"))
					l.setIdSla(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("maxDuration"))
					l.setIdMaxDuration(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("xmi.id"))
					key=attributes.getValue(i);
			}
			if(key!=null && !key.equals(""))
				latency.put(key, l);
		}
		
		if (element.endsWith(operationName.toLowerCase())) {
			OperationSlang o = new OperationSlang();
			String key="";
			for(int i=0;i<attributes.getLength();i++){
				if(attributes.getQName(i).equalsIgnoreCase("description"))
					o.setDescription(attributes.getValue(i));
				if(attributes.getQName(i).equalsIgnoreCase("xmi.id"))
					key=attributes.getValue(i);
			}
			if(key!=null && !key.equals(""))
				operation.put(key, o);
		}
	}

	public void endElement(String uri, String localName,
			String qName)
	throws SAXException {

	}
	
	public HashMap<String, Double> getDuration(){
		return this.duration;
	}
	
	public HashMap<String, ThroughputSlang> getThroughput(){
		return this.throughput;
	}
	
	public HashMap<String, String> getSla(){
		return this.sla;
	}
	
	public HashMap<String, OperationSlang> getOperation(){
		return this.operation;
	}
	
	public HashMap<String, LatencySlang> getLatency(){
		return this.latency;
	}
	
	private void convertIntoMs(String unit, double value, String key){
		double ms=-1;
		if (unit.equalsIgnoreCase("ms"))
			ms=value;
		else if (unit.equalsIgnoreCase("ns"))
			ms=value / 1000;
		else if (unit.equalsIgnoreCase("s"))
			ms=value * 1000;
		else if (unit.equalsIgnoreCase("min"))
			ms= value * 1000 * 60;
		else if (unit.equalsIgnoreCase("hr"))
			ms=value * 1000 * 60 * 60;
		else if (unit.equalsIgnoreCase("day"))
			ms=value * 1000 * 60 * 60 * 24; 
		if(ms>=0 )
			duration.put(key, ms);
	}


}
